﻿namespace anael.Data.Services
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    using System.Data;
    using System.Linq;
    using System.ServiceModel.DomainServices.EntityFramework;
    using System.ServiceModel.DomainServices.Hosting;
    using System.ServiceModel.DomainServices.Server;
    using anael.Data.Model;
    using anael.Data.BO;
    using anael.neuralNetwork;

    // Implements application logic using the ModelContainer context.
    // TODO: Add your application logic to these methods or in additional methods.
    // TODO: Wire up authentication (Windows/ASP.NET Forms) and uncomment the following to disable anonymous access
    // Also consider adding roles to restrict access as appropriate.
    // [RequiresAuthentication]
    [EnableClientAccess()]
    public class BODomainService : LinqToEntitiesDomainService<ModelContainer>
    {    
        public bool startLearning()
        {
            IQueryable <PersonneSet> pers =  this.ObjectContext.PersonneSet.Include("CategorieSet");
            
            List<EntriesTarget> listEntriesTarget = PersonneSet.NormalizeListOfPersonne(pers.ToList());

            CalculRN rn = new CalculRN(_alpha: 0.1, _nbrNeuroneCouche1: 22, _nbrNeuroneCouche2: 50, _nbrNeuroneCouche3: 7);

            Reseau res = rn.calculRetropropagation(listEntriesTarget);

            NeuralNetWork neuralNetWork = new NeuralNetWork();
            neuralNetWork.stream = SerializeManager.Serialize<Reseau>(res);

            this.ObjectContext.NeuralNetWork.AddObject(neuralNetWork);
            this.ObjectContext.SaveChanges();

            rn.calculActivite(listEntriesTarget[0], res);
            rn.calculActivite(listEntriesTarget[1], res);
            rn.calculActivite(listEntriesTarget[2], res);

            return true;
        }
        // TODO:
        // Consider constraining the results of your query method.  If you need additional input you can
        // add parameters to this method or create additional query methods with different names.
        // To support paging you will need to add ordering to the 'CategorieSet' query.
        public List<Potential> GetCategorieFromPerson(short _sexe, short _status, short _nbrContact, short _nbrPhoto, short _nbrGroupe)
        {
            PersonneSet personne = new PersonneSet() { sexe = _sexe, status = _status, nbrContact = _nbrContact, nbrPhoto = _nbrPhoto, nbrGroupe = _nbrGroupe };

            CalculRN rn = new CalculRN(_alpha: 0.1, _nbrNeuroneCouche1: 22, _nbrNeuroneCouche2: 50, _nbrNeuroneCouche3: 7);
            string strRes = (from it in this.ObjectContext.NeuralNetWork orderby it.Id descending select it.stream).FirstOrDefault();

            if (strRes != null)
            {
                List<Potential> pot = rn.calculActivite(PersonneSet.NormalizePersonne(personne), SerializeManager.Deserialize<Reseau>(strRes));
                return pot;
            }
            else
                return null;
        }

        // TODO:
        // Consider constraining the results of your query method.  If you need additional input you can
        // add parameters to this method or create additional query methods with different names.
        // To support paging you will need to add ordering to the 'PersonneSet' query.
        public IQueryable<PersonneSet> GetPersonneSet()
        {
            return this.ObjectContext.PersonneSet;
        }

        public void InsertPersonneSet(PersonneSet personneSet)
        {
            if ((personneSet.EntityState != EntityState.Detached))
            {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(personneSet, EntityState.Added);
            }
            else
            {
                this.ObjectContext.PersonneSet.AddObject(personneSet);
            }
        }

        public void UpdatePersonneSet(PersonneSet currentPersonneSet)
        {
            this.ObjectContext.PersonneSet.AttachAsModified(currentPersonneSet, this.ChangeSet.GetOriginal(currentPersonneSet));
        }

        public void DeletePersonneSet(PersonneSet personneSet)
        {
            if ((personneSet.EntityState == EntityState.Detached))
            {
                this.ObjectContext.PersonneSet.Attach(personneSet);
            }
            this.ObjectContext.PersonneSet.DeleteObject(personneSet);
        }
    }
}


